package com.nehc.nettyserver.netty.handler;

import com.nehc.nettyserver.common.Constants;
import com.nehc.nettyserver.service.ClientSessionService;
import com.nehc.nettyserver.service.MessageService;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * WebSocket帧处理器
 * 
 * @author nehc
 * @date 2023-04-02
 */
@Slf4j
@Sharable
@Component
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {

    @Autowired
    private ClientSessionService sessionService;

    @Autowired
    private MessageService messageService;

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.debug("Client connected: {}", ctx.channel().remoteAddress());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.debug("Client disconnected: {}", ctx.channel().remoteAddress());
        sessionService.removeSession(ctx.channel());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
        // 只处理文本帧
        if (frame instanceof TextWebSocketFrame) {
            String message = ((TextWebSocketFrame) frame).text();
            log.debug("Received message: {}", message);
            
            try {
                // 处理消息
                messageService.handleMessage(ctx.channel(), message);
                
                // 更新心跳时间
                sessionService.updateHeartbeat(ctx.channel());
            } catch (Exception e) {
                log.error("Error handling message: ", e);
                // 发送错误响应
                ctx.channel().writeAndFlush(new TextWebSocketFrame(
                        "{\"type\":\"" + Constants.MessageType.ERROR + "\",\"data\":\"" + e.getMessage() + "\"}"));
            }
        } else {
            // 其他类型的帧不处理，直接丢弃
            log.warn("Unsupported frame type: {}", frame.getClass().getName());
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("WebSocket handler exception: ", cause);
        sessionService.removeSession(ctx.channel());
        ctx.close();
    }
} 